/**
 *  @file
 *  @brief   两段直梁共线， 中间通过RBAR1连接
 *  @author  huangjingxiang
 *  @date    2024.05.13
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "DataStructure/Input/Constraint/RBAR1Data.h"
#include "DataStructure/Input/Element/CBARData.h"

#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Constraint/IRBAR1Service.h"
#include "DBManager/IService/Input/Element/IElementService.h"
#include "DBManager/IService/Input/Subcase/ISubcaseService.h"

using SG::DataStructure::FEM::DOFDirections;
using namespace SG::DBManager;
using SG::DataStructure::FEM::Subcase;
extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

class StraightBeam_LinkByRBAR1
{
  public:
    StraightBeam_LinkByRBAR1 ()
    {
        DB_SERVICEFACTORY->ClearDatabase ();
        Input (DB_SERVICEFACTORY);
    }

    /// @brief 写入模型数据
    void               Input (const DBServiceFactorySP dbServiceFactory);
    DBServiceFactorySP GetModel ()
    {
        return DB_SERVICEFACTORY;
    }
};

void StraightBeam_LinkByRBAR1::Input (const DBServiceFactorySP dbServiceFactory)
{
    // 节点写入
    {
        SG::DataStructure::FEM::NodeData node;
        node.m_id   = 1;
        node.m_x[0] = 0.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 2;
        node.m_x[0] = 1.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 3;
        node.m_x[0] = 1.5;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 4;
        node.m_x[0] = 2.5;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
    }
    // 截面属性写入
    {
        // SG::DataStructure::FEM::PRODData prod;
        // prod.m_id = 1;
        // prod.m_mId = 1;
        // prod.m_area = 0.5;
        // dbServiceFactory -> get<PRODService>()->Add (prod);
    }
    // 写入单元
    {
        SG::DataStructure::FEM::CBARData beam;
        beam.m_id   = 1;
        beam.m_g[0] = 1;
        beam.m_g[1] = 2;
        dbServiceFactory->get<IElementService> ()->Add (beam);

        beam.m_id   = 2;
        beam.m_g[0] = 3;
        beam.m_g[1] = 4;
        dbServiceFactory->get<IElementService> ()->Add (beam);
    }
    // 桌面使用RBE2 绑定 2和三号节点
    {
        SG::DataStructure::FEM::RBAR1Data rbar1;
        rbar1.m_id         = 3;
        rbar1.m_masterNode = 2;
        rbar1.m_slaveDOFs  = SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux,
                                                                   DOFDirections::DOF_Uy,
                                                                   DOFDirections::DOF_Uz,
                                                                   DOFDirections::DOF_Rotx,
                                                                   DOFDirections::DOF_Roty,
                                                                   DOFDirections::DOF_Rotz });
        rbar1.m_slaveNodes = 3;
        dbServiceFactory->get<IRBAR1Service> ()->Add (rbar1);
    }

    // 节点固定约束
    {
        SG::DataStructure::FEM::SPCData spc;
        spc.m_sId = 1;
        spc.m_g   = 1;
        spc.m_c   = SG::DataStructure::FEM::DofSet2Int ({ DOFDirections::DOF_Ux,
                                                          DOFDirections::DOF_Uy,
                                                          DOFDirections::DOF_Uz,
                                                          DOFDirections::DOF_Rotx,
                                                          DOFDirections::DOF_Roty,
                                                          DOFDirections::DOF_Rotz });
        spc.m_d   = 0;
        dbServiceFactory->get<ISPCService> ()->Add (spc);
    }

    // 工况
    {
        Subcase subcase;
        // subcase.m_id  = 1;
        // subcase.m_spc = 1;
        // dbServiceFactory->get<ISubcaseService> ()->Add (subcase);
        subcase.AddParameter({"SUBCASE","1"});
        subcase.AddParameter({"SOL","101"});
        subcase.AddParameter({"SPC","1"});
        std::cout<<subcase.Dump().Info();
        // subcase.AddParameter({"LOAD","1"});
        dbServiceFactory->get<ISubcaseService> ()->Initial (subcase.Dump());
    }
}